using UnityEngine;
using Framework;
using System;
using System.Collections.Generic;
using Framework.Save;

namespace GameCore
{
    public class LevelManager : MonoSingleton<LevelManager>
    {
        public string levelName;
        public LevelLoader levelLoader;
        
        
        public Transform inventoryRoot;
        public List<Inventory> inventories = new();

        public static void AddInventory(Inventory inventory)
        {
            inventory.transform.parent = Instance.inventoryRoot;
            Instance.inventories.Add(inventory);
        }

        public static void ClearInventory()
        {
            foreach (var inventory in Instance.inventories)
                if (inventory != null) Destroy(inventory.gameObject);
            Instance.inventories.Clear();
        }

        public static Transform ItemRoot => Instance.itemRoot;
        public Transform itemRoot;

        #region Region Management

        [Header("Region Management")]
        public PlayerBaseRegion baseRegion;
        public SimpleAdventureRegion adventureRegion;

        public static SimpleAdventureRegion GetCurrentAdventure() => Instance.adventureRegion;

        public static void EndAdventure(bool success)
        {
            if (success) Instance.baseRegion.playerInventory.SetData(Instance.adventureRegion.playerInventory.GetData());
            else Instance.baseRegion.playerInventory.ResetData();
            ClearInventory();
            Destroy(Instance.adventureRegion.gameObject);
            Instance.baseRegion.gameObject.SetActive(true);
            Instance.baseRegion.warehouseIcon.Select();
        }

        public static void BeginAdventure(ResourceID regionID)
        {
            Instance.adventureRegion = PrefabFactory.CreateInstance<Region>(regionID) as SimpleAdventureRegion;
            if (Instance.adventureRegion != null) Instance.baseRegion.gameObject.SetActive(false);
            ClearInventory();
        }
        
        #endregion

        protected override void Awake()
        {
            InitEventCenter();
        }

        private void Start()
        {
            levelLoader.Init();
            if (GameManager.TryGetValue("save_name", out var saveName))
                LoadSavedGame((string)saveName);
            else
                CreateNewGame();
        }
        
        #region Save

        public static void Save() => Instance._Save();
        private void _Save()
        {
            var json = JsonUtil.NewObject();
            json["base"] = baseRegion.Serialize();
            if (adventureRegion != null)
                json["adventure"] = adventureRegion.Serialize();
            SaveManager.Save(Instance.levelName, json, "saves");
        }

        private void CreateNewGame()
        {
            levelLoader.Init();
        }

        private void LoadSavedGame(string saveName)
        {
            levelLoader.Init();
            var json = SaveManager.Load(saveName, "saves");
            levelName = saveName;
            baseRegion.Deserialize(json["base"]);
            if (json.ContainsKey("adventure"))
            {
                adventureRegion = PrefabFactory.CreateInstance<Region>((string)json["adventure"]["regionID"]) as SimpleAdventureRegion;
                adventureRegion.Deserialize(json["adventure"]);
            }
            foreach (var key in json.Keys)
            {
                var region = PrefabFactory.CreateInstance<Region>(key);
                region.Deserialize(json[key]);
            }
        }

        #region Event

        private EventCenter eventCenter;
        private void InitEventCenter()
        {
            eventCenter = new EventCenter();
            eventCenter.AddTopic(new SimpleTopic<ItemPlacedEvent>());
        }

        public static void RaiseEvent<T>(T eventData) where T : EventData
        {
            Instance.eventCenter.RaiseEvent(eventData);
        }

        public static EventSubscription SubscribeEvent<T>(Action<T> handler) where T : EventData
        {
            Debug.Log($"Subscribing event: {typeof(T).Name}");
            return Instance.eventCenter.SubscribeEvent(handler);
        }
        
        #endregion

        #endregion
    }
}

